home *** CD-ROM | disk | FTP | other *** search
- /*
- * main.c -- main program for PCCTS ANTLR.
- *
- * $Id: main.c,v 1.9 1994/08/29 20:16:14 parrt Exp parrt $
- * $Revision: 1.9 $
- *
- * SOFTWARE RIGHTS
- *
- * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
- * Set (PCCTS) -- PCCTS is in the public domain. An individual or
- * company may do whatever they wish with source code distributed with
- * PCCTS or the code generated by PCCTS, including the incorporation of
- * PCCTS, or its output, into commerical software.
- *
- * We encourage users to develop software with PCCTS. However, we do ask
- * that credit is given to us for developing PCCTS. By "credit",
- * we mean that if you incorporate our source code into one of your
- * programs (commercial product, research project, or otherwise) that you
- * acknowledge this fact somewhere in the documentation, research report,
- * etc... If you like PCCTS and have developed a nice tool with the
- * output, please mention that you developed it using PCCTS. In
- * addition, we ask that this header remain intact in our source code.
- * As long as these guidelines are kept, we expect to continue enhancing
- * this system and expect to make other tools available as they are
- * completed.
- *
- * ANTLR 1.23
- * Terence Parr
- * Parr Research Corporation
- * with Purdue University and AHPCRC, University of Minnesota
- * 1989-1994
- */
-
- #include <stdio.h>
- #ifdef __cplusplus
- #ifndef __STDC__
- #define __STDC__
- #endif
- #endif
- #include "stdpccts.h"
-
- #define MAX_INT_STACK 50
- static int istack[MAX_INT_STACK]; /* Int stack */
- static int isp = MAX_INT_STACK;
-
- static int DontAcceptFiles = 0; /* if stdin, don't read files */
- static int DontAcceptStdin = 0; /* if files seen first, don't accept stdin */
-
-
- /* C m d - L i n e O p t i o n S t r u c t & F u n c s */
-
- typedef struct _Opt {
- char *option;
- int arg;
- #ifdef __cplusplus
- void (*process)(...);
- #else
- void (*process)();
- #endif
- char *descr;
- } Opt;
-
- #ifdef __STDC__
- extern void ProcessArgs(int, char **, Opt *);
- #else
- extern void ProcessArgs();
- #endif
-
- static void
- #ifdef __STDC__
- pStdin( void )
- #else
- pStdin( )
- #endif
- {
- if ( DontAcceptStdin )
- {
- warnNoFL("'-' (stdin) ignored as files were specified first");
- return;
- }
-
- require(NumFiles<MaxNumFiles,"exceeded max # of input files");
- FileStr[NumFiles++] = "stdin";
- DontAcceptFiles = 1;
- }
-
- static void
- #ifdef __STDC__
- pFile( char *s )
- #else
- pFile( s )
- char *s;
- #endif
- {
- if ( *s=='-' ) { warnNoFL( eMsg1("invalid option: '%s'",s) ); return; }
- if ( DontAcceptFiles )
- {
- warnNoFL(eMsg1("file '%s' ignored as '-' (stdin option) was specified first",s));
- return;
- }
-
- require(NumFiles<MaxNumFiles,"exceeded max # of input files");
- FileStr[NumFiles++] = s;
- DontAcceptStdin = 1;
- }
-
- static void
- #ifdef __STDC__
- pLLK( char *s, char *t )
- #else
- pLLK( s, t )
- char *s;
- char *t;
- #endif
- {
- LL_k = atoi(t);
- if ( LL_k <= 0 ) {
- warnNoFL("must have at least one token of lookahead (setting to 1)");
- LL_k = 1;
- }
- }
-
- static void
- #ifdef __STDC__
- pCk( char *s, char *t )
- #else
- pCk( s, t )
- char *s;
- char *t;
- #endif
- {
- CLL_k = atoi(t);
- if ( CLL_k <= 0 ) {
- warnNoFL("must have at least one token of look-ahead (setting to 1)");
- CLL_k = 1;
- }
- }
-
- #ifdef __STDC__
- static void pCGen(void) { CodeGen = FALSE; LexGen = FALSE; }
- static void pLGen(void) { LexGen = FALSE; }
- static void pTGen(void) { TraceGen = TRUE; }
- static void pSGen(void) { GenExprSets = FALSE; }
- static void pPrt(void) { PrintOut = TRUE; pCGen(); pLGen(); }
- static void pPrtA(void) { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
- static void pAst(void) { GenAST = TRUE; }
- static void pANSI(void) { GenANSI = TRUE; }
- static void pCr(void) { GenCR = TRUE; }
- static void pCt(void) { warnNoFL("-ct option is now the default"); }
- static void pLI(void) { GenLineInfo = TRUE; }
- static void pFr(char *s, char *t) {RemapFileName = t;}
- static void pFe(char *s, char *t) {ErrFileName = t;}
- static void pFl(char *s, char *t) {DlgFileName = t;}
- static void pFm(char *s, char *t) {ModeFileName = t;}
- static void pFt(char *s, char *t) {DefFileName = t;}
- static void pE1(void) { elevel = 1; }
- static void pE2(void) { elevel = 2; }
- static void pE3(void) { elevel = 3; }
- static void pEGen(void) { GenEClasseForRules = 1; }
- static void pDL(void) { DemandLookahead = 1; }
- static void pGHdr(void) { GenStdPccts = 1; }
- static void pFHdr(char *s, char *t) { stdpccts = t; pGHdr(); }
- static void pW1(void) { WarningLevel = 1; }
- static void pW2(void) { WarningLevel = 2; }
- static void pCC(void) { GenCC = TRUE; }
- #else
- static void pCGen() { CodeGen = FALSE; LexGen = FALSE; }
- static void pLGen() { LexGen = FALSE; }
- static void pTGen() { TraceGen = TRUE; }
- static void pSGen() { GenExprSets = FALSE; }
- static void pPrt() { PrintOut = TRUE; pCGen(); pLGen(); }
- static void pPrtA() { PrintOut = TRUE; PrintAnnotate = TRUE; pCGen(); pLGen(); }
- static void pAst() { GenAST = TRUE; }
- static void pANSI() { GenANSI = TRUE; }
- static void pCr() { GenCR = TRUE; }
- static void pCt() { warnNoFL("-ct option is now the default"); }
- static void pLI() { GenLineInfo = TRUE; }
- static void pFr(s,t) char *s, *t; {RemapFileName = t;}
- static void pFe(s,t) char *s, *t; {ErrFileName = t;}
- static void pFl(s,t) char *s, *t; {DlgFileName = t;}
- static void pFm(s,t) char *s, *t; {ModeFileName = t;}
- static void pFt(s,t) char *s, *t; {DefFileName = t;}
- static void pE1() { elevel = 1; }
- static void pE2() { elevel = 2; }
- static void pE3() { elevel = 3; }
- static void pEGen() { GenEClasseForRules = 1; }
- static void pDL() { DemandLookahead = 1; }
- static void pGHdr() { GenStdPccts = 1; }
- static void pFHdr(s,t) char *s, *t; { stdpccts = t; pGHdr(); }
- static void pW1() { WarningLevel = 1; }
- static void pW2() { WarningLevel = 2; }
- static void pCC() { GenCC = TRUE; }
- #endif
-
- static void
- #ifdef __STDC__
- pPre( char *s, char *t )
- #else
- pPre( s, t )
- char *s;
- char *t;
- #endif
- {
- RulePrefix = t;
- }
-
- static void
- #ifdef __STDC__
- pOut( char *s, char *t )
- #else
- pOut( s, t )
- char *s;
- char *t;
- #endif
- {
- OutputDirectory = t;
- }
-
- static void
- #ifdef __STDC__
- pPred( void )
- #else
- pPred( )
- #endif
- {
- warnNoFL("-pr is no longer used (predicates employed if present); see -prc");
- /*
- if ( DemandLookahead )
- warnNoFL("-gk conflicts with -pr; -gk turned off");
- DemandLookahead = 0;
- HoistPredicateContext = 0;
- */
- }
-
- static void
- #ifdef __STDC__
- pPredCtx( char *s, char *t )
- #else
- pPredCtx(s,t)
- char *s;
- char *t;
- #endif
- {
- if ( strcmp(t, "on")==0 ) HoistPredicateContext = 1;
- else if ( strcmp(t, "ON")==0 ) HoistPredicateContext = 1;
- else if ( strcmp(t, "off")==0 ) HoistPredicateContext = 0;
- else if ( strcmp(t, "OFF")==0 ) HoistPredicateContext = 0;
- if ( DemandLookahead )
- {
- warnNoFL("-gk incompatible with semantic predicate usage; -gk turned off");
- DemandLookahead = 0;
- }
- }
-
- static void
- #ifdef __STDC__
- pTRes( char *s, char *t )
- #else
- pTRes( s, t )
- char *s;
- char *t;
- #endif
- {
- TreeResourceLimit = atoi(t);
- if ( TreeResourceLimit <= 0 )
- {
- warnNoFL("analysis resource limit (# of tree nodes) must be greater than 0");
- TreeResourceLimit = -1; /* set to no limit */
- }
- }
-
- Opt options[] = {
- #ifdef __cplusplus
- { "-CC", 0, (void (*)(...)) pCC, "Generate C++ output (default=FALSE)"},
- { "-ck", 1, (void (*)(...)) pCk, "Set compressed lookahead depth; fast approximate lookahead"},
- { "-cr", 0, (void (*)(...)) pCr, "Generate cross reference (default=FALSE)"},
- { "-ct", 0, (void (*)(...)) pCt, "Do not copy tokens in C++ mode (default=to copy)"},*/
- { "-e1", 0, (void (*)(...)) pE1, "Ambiguities/errors shown in low detail (default)"},
- { "-e2", 0, (void (*)(...)) pE2, "Ambiguities/errors shown in more detail"},
- { "-e3", 0, (void (*)(...)) pE3, "Ambiguities/errors shown in excruciating detail"},
- { "-fe", 1, (void (*)(...)) pFe, "Rename err.c"},
- { "-fh", 1, (void (*)(...)) pFHdr, "Rename stdpccts.h header (turns on -gh)"},
- { "-fl", 1, (void (*)(...)) pFl, "Rename lexical output--parser.dlg"},
- { "-fm", 1, (void (*)(...)) pFm, "Rename mode.h"},
- { "-fr", 1, (void (*)(...)) pFr, "Rename remap.h"},
- { "-ft", 1, (void (*)(...)) pFt, "Rename tokens.h"},
- { "-ga", 0, (void (*)(...)) pANSI, "Generate ANSI-compatible code (default=FALSE)"},
- { "-gc", 0, (void (*)(...)) pCGen, "Do not generate output parser code (default=FALSE)"},
- { "-gd", 0, (void (*)(...)) pTGen, "Generate code to trace rule invocation (default=FALSE)"},
- { "-ge", 0, (void (*)(...)) pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
- { "-gh", 0, (void (*)(...)) pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
- { "-gk", 0, (void (*)(...)) pDL, "Generate parsers that delay lookahead fetches 'til needed"},
- { "-gl", 0, (void (*)(...)) pLI, "Generate line info about grammar actions in C parser"},
- { "-gp", 1, (void (*)(...)) pPre, "Prefix all generated rule functions with a string"},
- { "-gs", 0, (void (*)(...)) pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
- { "-gt", 0, (void (*)(...)) pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
- { "-gx", 0, (void (*)(...)) pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
- { "-k", 1, (void (*)(...)) pLLK, "Set full LL(k) lookahead depth (default==1)"},
- { "-o", 1, (void (*)(...)) pOut, OutputDirectoryOption},
- { "-p", 0, (void (*)(...)) pPrt, "Print out the grammar w/o actions (default=no)"},
- { "-pa", 0, (void (*)(...)) pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
- { "-pr",0, (void (*)(...)) pPred, "no longer used; predicates employed if present"},
- { "-prc", 1, (void (*)(...)) pPredCtx,"Turn on/off computation of context for hoisted predicates"},
- { "-rl", 1, (void (*)(...)) pTRes, "Limit max # of tree nodes used by grammar analysis"},
- { "-w1", 0, (void (*)(...)) pW1, "Set the warning level to 1 (default)"},
- { "-w2", 0, (void (*)(...)) pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
- { "-", 0, (void (*)(...)) pStdin, "Read grammar from stdin" },
- { "*", 0, (void (*)(...)) pFile, "" }, /* anything else is a file */
- #else
- { "-CC", 0, pCC, "Generate C++ output (default=FALSE)"},
- { "-cr", 0, pCr, "Generate cross reference (default=FALSE)"},
- { "-ct", 0, pCt, "Do not copy tokens in C++ mode (default=to copy)"},
- { "-ck", 1, pCk, "Set compressed lookahead depth; fast approximate lookahead"},
- { "-e1", 0, pE1, "Ambiguities/errors shown in low detail (default)"},
- { "-e2", 0, pE2, "Ambiguities/errors shown in more detail"},
- { "-e3", 0, pE3, "Ambiguities/errors shown in excrutiating detail"},
- { "-fe", 1, pFe, "Rename err.c"},
- { "-fh", 1, pFHdr, "Rename stdpccts.h header (turns on -gh)"},
- { "-fl", 1, pFl, "Rename lexical output--parser.dlg"},
- { "-fm", 1, pFm, "Rename mode.h"},
- { "-fr", 1, pFr, "Rename remap.h"},
- { "-ft", 1, pFt, "Rename tokens.h"},
- { "-ga", 0, pANSI, "Generate ANSI-compatible code (default=FALSE)"},
- { "-gc", 0, pCGen, "Do not generate output parser code (default=FALSE)"},
- { "-gd", 0, pTGen, "Generate code to trace rule invocation (default=FALSE)"},
- { "-ge", 0, pEGen, "Generate an error class for each non-terminal (default=FALSE)"},
- { "-gh", 0, pGHdr, "Generate stdpccts.h for non-ANTLR-generated-files to include"},
- { "-gk", 0, pDL, "Generate parsers that delay lookahead fetches 'til needed"},
- { "-gl", 0, pLI, "Generate line info about grammar actions in C parser"},
- { "-gp", 1, pPre, "Prefix all generated rule functions with a string"},
- { "-gs", 0, pSGen, "Do not generate sets for token expression lists (default=FALSE)"},
- { "-gt", 0, pAst, "Generate code for Abstract-Syntax-Trees (default=FALSE)"},
- { "-gx", 0, pLGen, "Do not generate lexical (dlg-related) files (default=FALSE)"},
- { "-k", 1, pLLK, "Set full LL(k) lookahead depth (default==1)"},
- { "-o", 1, pOut, OutputDirectoryOption},
- { "-p", 0, pPrt, "Print out the grammar w/o actions (default=no)"},
- { "-pa", 0, pPrtA, "Print out the grammar w/o actions & w/FIRST sets (default=no)"},
- { "-pr",0, pPred, "no longer used; predicates employed if present"},
- { "-prc", 1, pPredCtx,"Turn on/off computation of context for hoisted predicates"},
- { "-rl", 1, pTRes, "Limit max # of tree nodes used by grammar analysis"},
- { "-w1", 0, pW1, "Set the warning level to 1 (default)"},
- { "-w2", 0, pW2, "Ambiguities yield warnings even if predicates or (...)? block"},
- { "-", 0, pStdin, "Read grammar from stdin" },
- { "*", 0, pFile, "" }, /* anything else is a file */
- #endif
- { NULL, 0, NULL }
- };
-
- void readDescr();
- void cleanUp();
-
- #ifdef __STDC__
- static void buildRulePtr( void );
- static void help( void );
- static void init( void );
- static void CompleteTokenSetRefs( void );
- static void ensure_no_C_file_collisions(char *);
- #else
- static void buildRulePtr( );
- static void help( );
- static void init( );
- static void CompleteTokenSetRefs( );
- static void ensure_no_C_file_collisions();
- #endif
-
- /* M a i n */
-
- int
- #ifdef __STDC__
- main( int argc, char *argv[] )
- #else
- main( argc, argv )
- int argc;
- char *argv[];
- #endif
- {
- int i;
- static char EPSTR[] = "[Ep]";
-
- special_inits();
-
- fprintf(stderr, "Antlr parser generator Version %s 1989-1994\n", Version);
- if ( argc == 1 ) { help(); DIE; }
- ProcessArgs(argc-1, &(argv[1]), options);
-
- /* Fix lookahead depth */
- /* Compressed lookahead must always be larger than or equal to full lookahead */
- if ( CLL_k < LL_k && CLL_k>0 )
- {
- warnNoFL("must have compressed lookahead >= full LL(k) lookahead (setting -ck to -k)");
- CLL_k = LL_k;
- }
- if ( CLL_k == -1 ) CLL_k = LL_k;
- OutputLL_k = CLL_k;
- if ( ((CLL_k-1)&CLL_k)!=0 ) { /* output ll(k) must be power of 2 */
- int n;
- for(n=1; n<CLL_k; n<<=1) {;}
- OutputLL_k = n;
- }
-
- fpTrans = &(C_Trans[0]); /* Translate to C Language */
- fpJTrans = &(C_JTrans[0]);
- init();
- lexclass(LexStartSymbol);
-
- readDescr();
- LastTokenCounted = TokenNum;
- RemapForcedTokens();
- if ( CannotContinue ) {cleanUp(); DIE;}
- if ( GenCC && no_classes_found ) fatal("required grammar class not found (exiting...)");
- if ( WarningLevel>1 && HdrAction == NULL )
- warnNoFL("no #header action was found");
-
- EpToken = addTname(EPSTR); /* add imaginary token epsilon */
- set_orel(EpToken, &imag_tokens);
-
- /* this won't work for hand-built scanners since EofToken is not
- * known. Forces EOF to be token type 1.
- */
- set_orel(EofToken, &imag_tokens);
-
- set_size(NumWords(TokenNum-1));
-
- /* compute the set of all known token types
- * It represents the set of tokens from 1 to last_token_num + the
- * reserved positions above that (if any). Don't include the set of
- * imaginary tokens such as the token/error classes or EOF.
- */
- {
- set a;
- a = set_dup(reserved_positions);
- for (i=1; i<TokenNum; i++) { set_orel(i, &a); }
- all_tokens = set_dif(a, imag_tokens);
- set_free(a);
- }
-
- ComputeTokSets();
- CompleteTokenSetRefs();
-
- if ( CodeGen ) genDefFile(); /* create tokens.h */
- if ( LexGen ) genLexDescr(); /* create parser.dlg */
-
- if ( GenStdPccts )
- {
- FILE *f = fopen(OutMetaName(stdpccts), "w");
- if ( f==NULL ) {warnNoFL( eMsg1("can't create %s",OutMetaName(stdpccts)) );}
- else
- {
- special_fopen_actions(OutMetaName(stdpccts));
- genStdPCCTSIncludeFile(f);
- fclose(f);
- }
- }
-
- buildRulePtr(); /* create mapping from rule # to RuleBlk junction */
- ComputeErrorSets();
- FoLink( (Node *)SynDiag ); /* add follow links to end of all rules */
-
- if ( GenCR ) GenCrossRef( SynDiag );
-
- if ( CodeGen )
- {
- if ( SynDiag == NULL )
- {
- warnNoFL("no grammar description recognized");
- cleanUp();
- DIE;
- }
- else if ( !GenCC ) {
- ErrFile = fopen(OutMetaName(ErrFileName), "w");
- require(ErrFile != NULL, "main: can't open err file");
- special_fopen_actions(OutMetaName(ErrFileName));
- NewSetWd();
- GenErrHdr();
- TRANS(SynDiag); /* Translate to the target language */
- DumpSetWd();
- fclose( ErrFile );
- }
- else {
- strcpy(Parser_h_Name, CurrentClassName);
- strcat(Parser_h_Name, ".h");
- strcpy(Parser_c_Name, CurrentClassName);
- strcat(Parser_c_Name, CPP_FILE_SUFFIX);
- ensure_no_C_file_collisions(Parser_c_Name);
- Parser_h = fopen(OutMetaName(Parser_h_Name), "w");
- require(Parser_h != NULL, "main: can't open class Parserx.h file");
- special_fopen_actions(OutMetaName(Parser_h_Name));
- Parser_c = fopen(OutMetaName(Parser_c_Name), "w");
- require(Parser_c != NULL, "main: can't open class Parserx.c file");
- special_fopen_actions(OutMetaName(Parser_c_Name));
- GenParser_h_Hdr();
- GenParser_c_Hdr();
- NewSetWd();
- TRANS(SynDiag); /* Translate to the target language */
- DumpSetWd();
- GenRuleMemberDeclarationsForCC(Parser_h, SynDiag);
- /* Dump class members */
- if ( class_actions != NULL )
- {
- ListNode *p;
- for (p = class_actions->next; p!=NULL; p=p->next)
- {
- UserAction *ua = (UserAction *)p->elem;
- dumpAction( ua->action, Parser_h, 0, ua->file, ua->line, 1);
- }
- }
- fprintf(Parser_h, "};\n");
- fclose( Parser_h );
- fclose( Parser_c );
- }
- }
-
- if ( PrintOut )
- {
- if ( SynDiag == NULL ) {warnNoFL("no grammar description recognized");}
- else PRINT(SynDiag);
- }
-
- GenRemapFile(); /* create remap.h */
-
- cleanUp();
- #ifdef VAXC
- return 1; /* report all is well for make etc... */
- #else
- return 0; /* report all is well for make etc... */
- #endif
- }
-
- static void
- #ifdef __STDC__
- init( void )
- #else
- init( )
- #endif
- {
- Tname = newHashTable();
- Rname = newHashTable();
- Fcache = newHashTable();
- Tcache = newHashTable();
- reserved_positions = empty;
- all_tokens = empty;
- imag_tokens = empty;
- TokenStr = (char **) calloc(TSChunk, sizeof(char *));
- require(TokenStr!=NULL, "main: cannot allocate TokenStr");
- FoStack = (int **) calloc(CLL_k+1, sizeof(int *));
- require(FoStack!=NULL, "main: cannot allocate FoStack");
- FoTOS = (int **) calloc(CLL_k+1, sizeof(int *));
- require(FoTOS!=NULL, "main: cannot allocate FoTOS");
- Cycles = (ListNode **) calloc(CLL_k+1, sizeof(ListNode *));
- require(Cycles!=NULL, "main: cannot allocate Cycles List");
- }
-
- static void
- #ifdef __STDC__
- help( void )
- #else
- help( )
- #endif
- {
- Opt *p = options;
- fprintf(stderr, "antlr [options] f1 f2 ... fn\n");
- while ( *(p->option) != '*' )
- {
- fprintf(stderr, "\t%-4s %s %s\n",
- p->option,
- (p->arg)?"___":" ",
- p->descr);
- p++;
- }
- }
-
- /* The RulePtr array is filled in here. RulePtr exists primarily
- * so that sets of rules can be maintained for the FOLLOW caching
- * mechanism found in rJunc(). RulePtr maps a rule num from 1 to n
- * to a pointer to its RuleBlk junction where n is the number of rules.
- */
- static void
- #ifdef __STDC__
- buildRulePtr( void )
- #else
- buildRulePtr( )
- #endif
- {
- int r=1;
- Junction *p = SynDiag;
- RulePtr = (Junction **) calloc(NumRules+1, sizeof(Junction *));
- require(RulePtr!=NULL, "cannot allocate RulePtr array");
-
- while ( p!=NULL )
- {
- require(r<=NumRules, "too many rules???");
- RulePtr[r++] = p;
- p = (Junction *)p->p2;
- }
- }
-
- void
- #ifdef __STDC__
- dlgerror(char *s)
- #else
- dlgerror(s)
- char *s;
- #endif
- {
- fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
- fprintf(stderr, " lexical error: %s (text was '%s')\n",
- ((s == NULL) ? "Lexical error" : s), zzlextext);
- }
-
- void
- #ifdef __STDC__
- readDescr( void )
- #else
- readDescr( )
- #endif
- {
- zzerr = dlgerror;
- input = NextFile();
- if ( input==NULL ) fatal("No grammar description found (exiting...)");
- ANTLR(grammar(), input);
- }
-
- FILE *
- #ifdef __STDC__
- NextFile( void )
- #else
- NextFile( )
- #endif
- {
- FILE *f;
-
- for (;;)
- {
- CurFile++;
- if ( CurFile >= NumFiles ) return(NULL);
- if ( strcmp(FileStr[CurFile],"stdin") == 0 ) return stdin;
- f = fopen(FileStr[CurFile], "r");
- if ( f == NULL )
- {
- warnNoFL( eMsg1("file %s doesn't exist; ignored", FileStr[CurFile]) );
- }
- else
- {
- return(f);
- }
- }
- }
-
- /*
- * Return a string corresponding to the output file name associated
- * with the input file name passed in.
- *
- * Observe the following rules:
- *
- * f.e --> f".c"
- * f --> f".c"
- * f. --> f".c"
- * f.e.g --> f.e".c"
- *
- * Where f,e,g are arbitrarily long sequences of characters in a file
- * name.
- *
- * In other words, if a ".x" appears on the end of a file name, make it
- * ".c". If no ".x" appears, append ".c" to the end of the file name.
- *
- * C++ mode using .C not .c.
- *
- * Use malloc() for new string.
- */
- char *
- #ifdef __STDC__
- outname( char *fs )
- #else
- outname( fs )
- char *fs;
- #endif
- {
- static char buf[MaxFileName+1];
- char *p;
- require(fs!=NULL&&*fs!='\0', "outname: NULL filename");
-
- p = buf;
- strcpy(buf, fs);
- while ( *p != '\0' ) {p++;} /* Stop on '\0' */
- while ( *p != '.' && p != buf ) {--p;} /* Find '.' */
- if ( p != buf ) *p = '\0'; /* Found '.' */
- require(strlen(buf) + 2 < MaxFileName, "outname: filename too big");
- if ( GenCC ) strcat(buf, CPP_FILE_SUFFIX);
- else strcat(buf, ".c");
- return( buf );
- }
-
- void
- #ifdef __STDC__
- fatalFL( char *err_, char *f, int l )
- #else
- fatalFL( err_, f, l )
- char *err_;
- char *f;
- int l;
- #endif
- {
- fprintf(stderr, ErrHdr, f, l);
- fprintf(stderr, " %s\n", err_);
- cleanUp();
- exit(1);
- }
-
- void
- #ifdef __STDC__
- fatal_intern( char *err_, char *f, int l )
- #else
- fatal_intern( err_, f, l )
- char *err_;
- char *f;
- int l;
- #endif
- {
- fprintf(stderr, ErrHdr, f, l);
- fprintf(stderr, " #$%%*&@# internal error: %s\n", err_);
- fprintf(stderr, ErrHdr, f, l);
- fprintf(stderr, " [complain to nearest government official\n");
- fprintf(stderr, ErrHdr, f, l);
- fprintf(stderr, " or send hate-mail to parrt@acm.org;\n");
- fprintf(stderr, ErrHdr, f, l);
- fprintf(stderr, " please pray to the ``bug'' gods that there is a trival fix.]\n");
- cleanUp();
- exit(1);
- }
-
- void
- #ifdef __STDC__
- cleanUp( void )
- #else
- cleanUp( )
- #endif
- {
- if ( DefFile != NULL) fclose( DefFile );
- }
-
- /* sprintf up to 3 strings */
- char *
- #ifdef __STDC__
- eMsg3( char *s, char *a1, char *a2, char *a3 )
- #else
- eMsg3( s, a1, a2, a3 )
- char *s;
- char *a1;
- char *a2;
- char *a3;
- #endif
- {
- static char buf[250]; /* DANGEROUS as hell !!!!!! */
-
- sprintf(buf, s, a1, a2, a3);
- return( buf );
- }
-
- /* sprintf a decimal */
- char *
- #ifdef __STDC__
- eMsgd( char *s, int d )
- #else
- eMsgd( s, d )
- char *s;
- int d;
- #endif
- {
- static char buf[250]; /* DANGEROUS as hell !!!!!! */
-
- sprintf(buf, s, d);
- return( buf );
- }
-
- void
- #ifdef __STDC__
- s_fprT( FILE *f, set e )
- #else
- s_fprT( f, e )
- FILE *f;
- set e;
- #endif
- {
- register unsigned *p;
- unsigned *q;
-
- if ( set_nil(e) ) return;
- if ( (q=p=set_pdq(e)) == NULL ) fatal_internal("Can't alloc space for set_pdq");
- fprintf(f, "{");
- while ( *p != nil )
- {
- fprintf(f, " %s", TerminalString(*p));
- p++;
- }
- fprintf(f, " }");
- free((char *)q);
- }
-
- /* Return the token name or regular expression for a token number. */
- char *
- #ifdef __STDC__
- TerminalString( int token )
- #else
- TerminalString( token )
- int token;
- #endif
- {
- int j;
-
- /* look in all lexclasses for the token */
- if ( TokenString(token) != NULL ) return TokenString(token);
- for (j=0; j<NumLexClasses; j++)
- {
- lexmode(j);
- if ( ExprString(token) != NULL ) return ExprString(token);
- }
- require(j<NumLexClasses, eMsgd("No label or expr for token %d",token));
- return "invalid";
- }
-
- /* S i m p l e I n t S t a c k */
-
- void
- #ifdef __STDC__
- pushint( int i )
- #else
- pushint( i )
- int i;
- #endif
- {
- require(isp>0, "pushint: stack overflow");
- istack[--isp] = i;
- }
-
- int
- #ifdef __STDC__
- popint( void )
- #else
- popint( )
- #endif
- {
- require(isp<MAX_INT_STACK, "popint: stack underflow");
- return istack[isp++];
- }
-
- int
- #ifdef __STDC__
- istacksize( void )
- #else
- istacksize( )
- #endif
- {
- return MAX_INT_STACK-isp;
- }
-
- void
- #ifdef __STDC__
- istackreset( void )
- #else
- istackreset( )
- #endif
- {
- isp = MAX_INT_STACK;
- }
-
- int
- #ifdef __STDC__
- istackempty( void )
- #else
- istackempty( )
- #endif
- {
- return isp==MAX_INT_STACK;
- }
-
- int
- #ifdef __STDC__
- topint( void )
- #else
- topint( )
- #endif
- {
- require(isp<MAX_INT_STACK, "topint: stack underflow");
- return istack[isp];
- }
-
- void
- #ifdef __STDC__
- ProcessArgs( int argc, char **argv, Opt *options )
- #else
- ProcessArgs( argc, argv, options )
- int argc;
- char **argv;
- Opt *options;
- #endif
- {
- Opt *p;
- require(argv!=NULL, "ProcessArgs: command line NULL");
-
- while ( argc-- > 0 )
- {
- p = options;
- while ( p->option != NULL )
- {
- if ( strcmp(p->option, "*") == 0 ||
- strcmp(p->option, *argv) == 0 )
- {
- if ( p->arg )
- {
- (*p->process)( *argv, *(argv+1) );
- argv++;
- argc--;
- }
- else
- (*p->process)( *argv );
- break;
- }
- p++;
- }
- argv++;
- }
- }
-
- /* Go back into the syntax diagram and compute all meta tokens; i.e.
- * turn all '.', ranges, token class refs etc... into actual token sets
- */
- static void
- CompleteTokenSetRefs()
- {
- ListNode *p;
-
- if ( MetaTokenNodes==NULL ) return;
- for (p = MetaTokenNodes->next; p!=NULL; p=p->next)
- {
- set a,b;
-
- TokNode *q = (TokNode *)p->elem;
- if ( q->wild_card )
- {
- q->tset = all_tokens;
- }
- else if ( q->tclass!=NULL )
- {
- if ( q->complement ) q->tset = set_dif(all_tokens, q->tclass->tset);
- else q->tset = q->tclass->tset;
- }
- else if ( q->upper_range!=0 )
- {
- /* we have a range on our hands: make a set from q->token .. q->upper_range */
- int i;
- a = empty;
- for (i=q->token; i<=(int)q->upper_range; i++) { set_orel(i, &a); }
- q->tset = a;
- }
- /* at this point, it can only be a complemented single token */
- else if ( q->complement )
- {
- a = set_of(q->token);
- b = set_dif(all_tokens, a);
- set_free(a);
- q->tset=b;
- }
- else fatal("invalid meta token");
- }
- }
-
- char *
- #ifdef __STDC__
- OutMetaName(char *n)
- #else
- OutMetaName(n)
- char *n;
- #endif
- {
- static char buf[MaxFileName+1];
-
- if ( strcmp(OutputDirectory,TopDirectory)==0 ) return n;
- strcpy(buf, OutputDirectory);
- if ( strcmp(&buf[strlen(buf) - 1], DirectorySymbol ) )
- strcat(buf, DirectorySymbol);
- strcat(buf, n);
- return buf;
- }
-
- static void
- #ifdef __STDC__
- ensure_no_C_file_collisions(char *class_c_file)
- #else
- ensure_no_C_file_collisions(class_c_file)
- char *class_c_file;
- #endif
- {
- int i;
-
- for (i=0; i<NumFiles; i++)
- {
- #ifdef PC
- /* assume that file names are case insensitive */
- if ( strcasecmp(outname(FileStr[i]), class_c_file)==0 )
- #else
- if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
- #endif
- {
- fatal(eMsg1("class def output file conflicts with parser output file: %s",
- outname(FileStr[i])));
- }
- }
- }
-
- void
- #ifdef __STDC__
- warnNoFL(char *err)
- #else
- warnNoFL(err)
- char *err;
- #endif
- {
- fprintf(stderr, "warning: %s\n", err);
- }
-
- void
- #ifdef __STDC__
- warnFL(char *err,char *f,int l)
- #else
- warnFL(err,f,l)
- char *f;
- int l;
- char *err;
- #endif
- {
- fprintf(stderr, ErrHdr, f, l);
- fprintf(stderr, " warning: %s\n", err);
- }
-
- void
- #ifdef __STDC__
- warn(char *err)
- #else
- warn(err)
- char *err;
- #endif
- {
- /* back up the file number if we hit an error at the end of the last file */
- if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
- fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
- fprintf(stderr, " warning: %s\n", err);
- }
-
- void
- #ifdef __STDC__
- warnNoCR( char *err )
- #else
- warnNoCR( err )
- char *err;
- #endif
- {
- /* back up the file number if we hit an error at the end of the last file */
- if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
- fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
- fprintf(stderr, " warning: %s", err);
- }
-
- void
- #ifdef __STDC__
- errNoFL(char *err)
- #else
- errNoFL(err)
- char *err;
- #endif
- {
- fprintf(stderr, "error: %s\n", err);
- }
-
- void
- #ifdef __STDC__
- errFL(char *err,char *f,int l)
- #else
- errFL(err,f,l)
- char *err;
- char *f;
- int l;
- #endif
- {
- fprintf(stderr, ErrHdr, f, l);
- fprintf(stderr, " error: %s\n", err);
- }
-
- void
- #ifdef __STDC__
- err(char *err)
- #else
- err(err)
- char *err;
- #endif
- {
- /* back up the file number if we hit an error at the end of the last file */
- if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
- fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
- fprintf(stderr, " error: %s\n", err);
- }
-
- void
- #ifdef __STDC__
- errNoCR( char *err )
- #else
- errNoCR( err )
- char *err;
- #endif
- {
- /* back up the file number if we hit an error at the end of the last file */
- if ( CurFile >= NumFiles && CurFile >= 1 ) CurFile--;
- fprintf(stderr, ErrHdr, FileStr[CurFile], zzline);
- fprintf(stderr, " error: %s", err);
- }
-
- UserAction *
- #ifdef __STDC__
- newUserAction(char *s)
- #else
- newUserAction(s)
- char *s;
- #endif
- {
- UserAction *ua = (UserAction *) calloc(1, sizeof(UserAction));
- require(ua!=NULL, "cannot allocate UserAction");
-
- ua->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));
- strcpy(ua->action, s);
- return ua;
- }
-